/**
 * @author richt / http://richt.me
 * @author WestLangley / http://github.com/WestLangley
 *
 * W3C Device Orientation control (http://w3c.github.io/deviceorientation/spec-source-orientation.html)
 */

import * as THREE from 'three'
/* eslint-disable */
THREE.DeviceOrientationControls = function( object ) {
  var scope = this;

  this.object = object;
  this.object.rotation.reorder( "YXZ" );

  this.enabled = true;

  this.deviceOrientation = {};
  this.screenOrientation = 0;

  this.alphaOffset = 0; // radians

  var onDeviceOrientationChangeEvent = function( event ) {

    scope.deviceOrientation = event;

  };

  var onScreenOrientationChangeEvent = function() {

    scope.screenOrientation = window.orientation || 0;

  };

  // The angles alpha, beta and gamma form a set of intrinsic Tait-Bryan angles of type Z-X'-Y''

  var setObjectQuaternion = function() {

    var zee = new THREE.Vector3( 0, 0, 1 );

    var euler = new THREE.Euler();

    var q0 = new THREE.Quaternion();

    var q1 = new THREE.Quaternion( - Math.sqrt( 0.5 ), 0, 0, Math.sqrt( 0.5 ) ); // - PI/2 around the x-axis

    return function( quaternion, alpha, beta, gamma, orient ) {

      euler.set( beta, alpha, - gamma, 'YXZ' ); // 'ZXY' for the device, but 'YXZ' for us

      quaternion.setFromEuler( euler ); // orient the device

      quaternion.multiply( q1 ); // camera looks out the back of the device, not the top

      quaternion.multiply( q0.setFromAxisAngle( zee, - orient ) ); // adjust for screen orientation

    }

  }();

  this.connect = function() {

    onScreenOrientationChangeEvent(); // run once on load

    window.addEventListener( 'orientationchange', onScreenOrientationChangeEvent, false );
    window.addEventListener( 'deviceorientation', onDeviceOrientationChangeEvent, false );

    scope.enabled = true;

  };

  this.disconnect = function() {

    window.removeEventListener( 'orientationchange', onScreenOrientationChangeEvent, false );
    window.removeEventListener( 'deviceorientation', onDeviceOrientationChangeEvent, false );

    scope.enabled = false;

  };

  this.getDeviceOrientationRad = function () {
    var alpha = scope.deviceOrientation.alpha ? THREE.Math.degToRad( scope.deviceOrientation.alpha ) + this.alphaOffset : 0; // Z
    var beta = scope.deviceOrientation.beta ? THREE.Math.degToRad( scope.deviceOrientation.beta ) : 0; // X'
    var gamma = scope.deviceOrientation.gamma ? THREE.Math.degToRad( scope.deviceOrientation.gamma ) : 0; // Y''
    return {x: alpha, y: beta, z: gamma};
  }

  this.getDeviceOrientationDeg = function () {
    var alpha = scope.deviceOrientation.alpha ? scope.deviceOrientation.alpha + THREE.Math.radToDeg(this.alphaOffset): 0; // Z
    var beta = scope.deviceOrientation.beta ? scope.deviceOrientation.beta : 0; // X'
    var gamma = scope.deviceOrientation.gamma ? scope.deviceOrientation.gamma : 0; // Y''
    return {x: alpha, y: beta, z: gamma};
  }

  this.update = function() {

    if ( scope.enabled === false ) return;

    var alpha = scope.deviceOrientation.alpha ? THREE.Math.degToRad( scope.deviceOrientation.alpha ) + this.alphaOffset : 0; // Z
    var beta = scope.deviceOrientation.beta ? THREE.Math.degToRad( scope.deviceOrientation.beta ) : 0; // X'
    var gamma = scope.deviceOrientation.gamma ? THREE.Math.degToRad( scope.deviceOrientation.gamma ) : 0; // Y''
    var orient = scope.screenOrientation ? THREE.Math.degToRad( scope.screenOrientation ) : 0; // O

    setObjectQuaternion( scope.object.quaternion, alpha, beta, gamma, orient );
  };


  this.cpUpdate = function (data) {
    let x = scope.deviceOrientation.alpha;
    let y = scope.deviceOrientation.beta;
    let z = scope.deviceOrientation.gamma;
    if (data){
      let {position, orientation} = data;
      if (orientation){
        if (orientation.hasOwnProperty('x')){
          x = orientation.x;
        } else {
          let planeX = Math.cos(orientation.a) - orientation.r * Math.sin(orientation.a);
          let planeY = Math.sin(orientation.a) + orientation.r * Math.cos(orientation.a);
          // console.log(orientation.a + ' | ' + orientation.r)
          // console.log(planeY + ' | ' + planeX);
          // console.log(THREE.Math.radToDeg(Math.atan2(planeY, planeX)))
          x = THREE.Math.radToDeg(Math.atan2(planeY, planeX));
        }
        y = orientation.y;
        z = orientation.z;
      }
      if (position){
        scope.object.position.set(position.r*Math.cos(position.a), position.y, position.r*Math.sin(position.a))
      }
    }
    var alpha = x ? THREE.Math.degToRad( x ) + this.alphaOffset : 0; // Z
    var beta = y ? THREE.Math.degToRad( y ) : 0; // X'
    var gamma = z ? THREE.Math.degToRad( z ) : 0; // Y''
    var orient = scope.screenOrientation ? THREE.Math.degToRad( scope.screenOrientation ) : 0; // O
    setObjectQuaternion( scope.object.quaternion, alpha, beta, gamma, orient )
    // setObjectQuaternion( scope.object.quaternion, 0, beta, gamma, orient )
  }

  this.dispose = function() {

    this.disconnect();

  };

  this.connect();

};
/* eslint-disable */
